package com.stack.knowyouservice.service.impl;

import com.stack.knowyoubase.anotional.TimeOut;
import com.stack.knowyoubean.bean.CourseAtlas;
import com.stack.knowyoudao.dao.CourseAtlasDao;
import com.stack.knowyouservice.service.CourseAtlasService;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 图谱服务层
 *
 * @author stack
 */
@Service
@Scope("singleton")
public class CourseAtlasServiceImpl implements CourseAtlasService {

    @Resource
    private CourseAtlasDao courseAtlasDao;

    @Transactional(readOnly = true, rollbackFor = Throwable.class)
    @TimeOut
    @Override
    public CourseAtlas courseAtlasSearch(String source, Integer sid) {
        CourseAtlas courseAtlas = new CourseAtlas();
        List<CourseAtlas.Edge> atlasEdge;
        List<CourseAtlas.Node> atlasNode;
        Map<String, CourseAtlas.Node> nodeMap = new HashMap<>();
        if (StringUtils.isEmpty(source)) {
            atlasEdge = courseAtlasDao.findAtlasEdge(null, sid);
            atlasNode = courseAtlasDao.findAllNode(sid);
            for (CourseAtlas.Node node : atlasNode) {
                nodeMap.put(String.valueOf(node.getNodeid()), node);
            }
        } else {
            CourseAtlas.Node rootNode = courseAtlasDao.findNodeByName(source, sid);
            if (rootNode != null) {
                nodeMap.put(String.valueOf(rootNode.getNodeid()), rootNode);
                atlasEdge = courseAtlasDao.findAtlasEdge(rootNode.getNodeid(), sid);
                atlasNode = courseAtlasDao.findAtlasNode(rootNode.getNodeid(), sid);
                for (CourseAtlas.Node node : atlasNode) {
                    nodeMap.put(String.valueOf(node.getNodeid()), node);
                }
            } else {
                atlasEdge = null;
            }
        }
        courseAtlas.setEdges(atlasEdge);
        courseAtlas.setNodes(nodeMap);
        return courseAtlas;
    }

    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
    @TimeOut
    @Override
    public boolean atlasNodeAdd(CourseAtlas.Node node) {
        //校验名称字段
        if (StringUtils.isEmpty(node.getName())) {
            return false;
        } else {
            //判断节点是否存在
            CourseAtlas.Node nodeByName = courseAtlasDao.findNodeByName(node.getName(), node.getSid());
            //节点不存在才可添加(有此节点)
            if (nodeByName != null) {
                return false;
            } else {
                int i = courseAtlasDao.insertNode(node);
                return i == 1;
            }
        }
    }

    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
    @TimeOut
    @Override
    public boolean atlasNodeUpdate(CourseAtlas.Node node) {
        //校验名称字段
        if (StringUtils.isEmpty(node.getName())) {
            return false;
        } else {
            //判断节点是否存在
            CourseAtlas.Node nodeByName = courseAtlasDao.findNodeByName(node.getName(), node.getSid());
            //节点是存在的才可更新（不存在）
            if (nodeByName == null) {
                return false;
            } else {
                int i = courseAtlasDao.updateNode(node);
                return i == 1;
            }
        }
    }

    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
    @TimeOut
    @Override
    public boolean atlasNodeDelete(CourseAtlas.Node node) {
        //校验名称字段
        if (StringUtils.isEmpty(node.getName())) {
            return false;
        } else {
            //判断节点是否存在,不存在则不需删除
            CourseAtlas.Node nodeByName = courseAtlasDao.findNodeByName(node.getName(), node.getSid());
            //节点不存在，直接删除成功
            if (nodeByName == null) {
                return true;
            }
            //节点存在
            else {
                //删除包含节点的边
                courseAtlasDao.deleteNodeEdge(node);
                //删除节点
                int i = courseAtlasDao.deleteNode(node);
                return i == 1;
            }
        }
    }

    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
    @TimeOut
    @Override
    public boolean atlasEdgeAdd(String preName, String afterName, String rela, Integer sid) {
        //校验起点和终点是否为空
        if (StringUtils.isEmpty(preName) || StringUtils.isEmpty(afterName)) {
            return false;
        } else {
            //查询两个点判断是否存在
            CourseAtlas.Node preNode = courseAtlasDao.findNodeByName(preName, sid);
            CourseAtlas.Node afterNode = courseAtlasDao.findNodeByName(afterName, sid);
            if (preNode == null || afterNode == null) {
                return false;
            } else {
                //判断边是否存在
                CourseAtlas.Edge edge = new CourseAtlas.Edge(preNode.getNodeid(), afterNode.getNodeid(), rela, sid);
                CourseAtlas.Edge isEdge = courseAtlasDao.findEdge(edge);
                if (isEdge != null) {
                    return false;
                } else {
                    int i = courseAtlasDao.insertEdge(edge);
                    return i == 1;
                }
            }
        }
    }

    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
    @TimeOut
    @Override
    public boolean atlasEdgeUpdate(String preName, String afterName, String rela, Integer sid) {
        //校验起点和终点是否为空
        if (StringUtils.isEmpty(preName) || StringUtils.isEmpty(afterName)) {
            return false;
        } else {
            //查询两个点判断是否存在
            CourseAtlas.Node preNode = courseAtlasDao.findNodeByName(preName, sid);
            CourseAtlas.Node afterNode = courseAtlasDao.findNodeByName(afterName, sid);
            if (preNode == null || afterNode == null) {
                return false;
            } else {
                //判断边是否存在
                CourseAtlas.Edge edge = new CourseAtlas.Edge(preNode.getNodeid(), afterNode.getNodeid(), rela, sid);
                CourseAtlas.Edge isEdge = courseAtlasDao.findEdge(edge);
                if (isEdge == null) {
                    return false;
                } else {
                    int i = courseAtlasDao.updateEdge(edge);
                    return i == 1;
                }
            }
        }
    }

    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
    @TimeOut
    @Override
    public boolean atlasEdgeDelete(String preName, String afterName, Integer sid) {
        //校验起点和终点是否为空
        if (StringUtils.isEmpty(preName) || StringUtils.isEmpty(afterName)) {
            return false;
        } else {
            //查询两个点判断是否存在
            CourseAtlas.Node preNode = courseAtlasDao.findNodeByName(preName, sid);
            CourseAtlas.Node afterNode = courseAtlasDao.findNodeByName(afterName, sid);
            if (preNode == null || afterNode == null) {
                return false;
            } else {
                //判断边是否存在
                CourseAtlas.Edge edge = new CourseAtlas.Edge(preNode.getNodeid(), afterNode.getNodeid(), null, sid);
                CourseAtlas.Edge isEdge = courseAtlasDao.findEdge(edge);
                if (isEdge == null) {
                    return true;
                } else {
                    int i = courseAtlasDao.deleteEdge(edge);
                    return i == 1;
                }
            }
        }
    }


}
